<template>
  <div class="workflow-page">
    <div class="toolbar">
      <div class="toolbar-right">
        <button class="add-node-btn" @click="addNode">添加节点</button>
      </div>
    </div>
    <div class="workflow-container" @drop.prevent="handleDrop" @dragover.prevent>
      <!-- 所有节点 -->
      <Node 
        v-for="node in nodes"
        :key="node.id"
        :node="node"
        :edges="getEdgesForNode(node)"
        @dragstart="(event) => handleDragStart(event, node)"
        @dragend="handleDragEnd"
        @delete="() => deleteNode(node.id)"
        @startConnection="handleStartConnection"
        @endConnection="handleEndConnection"
      />
  
      <!-- 连线 -->
      <svg class="connections">
        <!-- 临时连线 -->
        <path
          v-if="tempConnection.isActive"
          :d="tempConnection.path"
          stroke="#2196f3"
          stroke-dasharray="5,5"
          fill="none"
          stroke-width="2"
        />
        <!-- 已有连线 -->
        <path 
          v-for="edge in edges" 
          :key="`${edge.sourceId}-${edge.targetId}`"
          :d="edge.path"
          stroke="#2196f3"
          fill="none"
          stroke-width="2"
          class="edge-path"
          @click="deleteEdge(edge)"
        />
      </svg>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed } from 'vue';
  import Node from './Node.vue';
  import { NodeType } from '../types';
  
  const nodes = ref<Node[]>([
    { id: 'n1', x: 50, y: 50, isParent: true, type: NodeType.START, children: ['n2'] },
    { id: 'n2', x: 200, y: 200, type: NodeType.NORMAL }
  ]);

  // 临时连线状态
  const tempConnection = ref({
    isActive: false,
    sourceId: '',
    startX: 0,
    startY: 0,
    endX: 0,
    endY: 0,
    path: ''
  });

  // 计算贝塞尔曲线路径
  const getBezierPath = (start: { x: number; y: number }, end: { x: number; y: number }) => {
    const deltaX = Math.abs(end.x - start.x);
    const deltaY = Math.abs(end.y - start.y);
    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
    
    // 设置最小和最大偏移量
    const minOffset = 20;
    const maxOffset = 60;
    
    // 根据距离计算偏移量，使用平方根函数使增长更平缓
    const controlPointOffset = Math.min(maxOffset, Math.max(minOffset, Math.sqrt(distance) * 2));
    
    const startControl = { x: start.x + controlPointOffset, y: start.y };
    const endControl = { x: end.x - controlPointOffset, y: end.y };
    
    return `M ${start.x},${start.y} C ${startControl.x},${startControl.y} ${endControl.x},${endControl.y} ${end.x},${end.y}`;
  };

  // 处理鼠标移动
  const handleMouseMove = (event: MouseEvent) => {
    if (tempConnection.value.isActive) {
      const rect = document.querySelector('.workflow-container')?.getBoundingClientRect();
      if (rect) {
        const x = event.clientX - rect.left;
        const y = event.clientY - rect.top;
        tempConnection.value.endX = x;
        tempConnection.value.endY = y;
        tempConnection.value.path = getBezierPath(
          { x: tempConnection.value.startX, y: tempConnection.value.startY },
          { x: x, y: y }
        );
      }
    }
  };

  // 处理开始连线
  const handleStartConnection = ({ nodeId, event }: { nodeId: string, event: MouseEvent }) => {
    const rect = document.querySelector('.workflow-container')?.getBoundingClientRect();
    if (rect) {
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;
      tempConnection.value = {
        isActive: true,
        sourceId: nodeId,
        startX: x,
        startY: y,
        endX: x,
        endY: y,
        path: ''
      };
      document.addEventListener('mousemove', handleMouseMove);
    }
  };

  // 根据角度获取源节点的连接点
  const getSourceConnectionPoint = (sourcePoints: any, angle: number, absAngle: number) => {
    if (absAngle <= Math.PI / 4) { // 右
      return sourcePoints.right;
    } else if (absAngle >= 3 * Math.PI / 4) { // 左
      return sourcePoints.left;
    } else if (angle > 0) { // 下
      return sourcePoints.bottom;
    } else { // 上
      return sourcePoints.top;
    }
  };

  // 根据角度获取目标节点的连接点
  const getTargetConnectionPoint = (targetPoints: any, angle: number, absAngle: number) => {
    if (absAngle <= Math.PI / 4) { // 右
      return targetPoints.left;
    } else if (absAngle >= 3 * Math.PI / 4) { // 左
      return targetPoints.right;
    } else if (angle > 0) { // 下
      return targetPoints.top;
    } else { // 上
      return targetPoints.bottom;
    }
  };

  // 计算连线的起点和终点位置
  const calculateConnectionPoints = (sourceNode: Node, targetNode: Node) => {
    const nodeWidth = 80;
    const nodeHeight = 32;
    
    // 计算节点中心点
    const sourceCenter = {
      x: sourceNode.x + nodeWidth / 2,
      y: sourceNode.y + nodeHeight / 2
    };
    const targetCenter = {
      x: targetNode.x + nodeWidth / 2,
      y: targetNode.y + nodeHeight / 2
    };
    
    // 计算两个节点的相对位置关系
    const deltaX = targetCenter.x - sourceCenter.x;
    const deltaY = targetCenter.y - sourceCenter.y;
    
    // 计算节点间的角度
    const angle = Math.atan2(deltaY, deltaX);
    const absAngle = Math.abs(angle);
    
    // 定义节点边界的四个点
    const sourcePoints = {
      top: { x: sourceCenter.x, y: sourceNode.y },
      right: { x: sourceNode.x + nodeWidth, y: sourceCenter.y },
      bottom: { x: sourceCenter.x, y: sourceNode.y + nodeHeight },
      left: { x: sourceNode.x, y: sourceCenter.y }
    };
    
    const targetPoints = {
      top: { x: targetCenter.x, y: targetNode.y },
      right: { x: targetNode.x + nodeWidth, y: targetCenter.y },
      bottom: { x: targetCenter.x, y: targetNode.y + nodeHeight },
      left: { x: targetNode.x, y: targetCenter.y }
    };
    
    // 根据角度获取连接点
    const startPoint = getSourceConnectionPoint(sourcePoints, angle, absAngle);
    const endPoint = getTargetConnectionPoint(targetPoints, angle, absAngle);
    
    return {
      startX: startPoint.x,
      startY: startPoint.y,
      endX: endPoint.x,
      endY: endPoint.y
    };
  };

  // 计算所有边的路径
  const edges = computed(() => {
    const result: Edge[] = [];
    nodes.value.forEach(node => {
      if (node.children) {
        node.children.forEach(childId => {
          const childNode = nodes.value.find(n => n.id === childId);
          if (childNode) {
            const points = calculateConnectionPoints(node, childNode);
            result.push({
              sourceId: node.id,
              targetId: childId,
              path: getBezierPath(
                { x: points.startX, y: points.startY },
                { x: points.endX, y: points.endY }
              )
            });
          }
        });
      }
    });
    return result;
  });

  // 删除连线
  const deleteEdge = (edge: Edge) => {
    const sourceNode = nodes.value.find(n => n.id === edge.sourceId);
    if (sourceNode && sourceNode.children) {
      sourceNode.children = sourceNode.children.filter(id => id !== edge.targetId);
      if (sourceNode.children.length === 0) {
        sourceNode.isParent = false;
      }
      // 更新连线的视觉效果
      const updatedEdges = edges.value.filter(e => 
        e.sourceId !== edge.sourceId || e.targetId !== edge.targetId
      );
      edges.value = updatedEdges;
    }
  };

  // 处理结束连线
  const handleEndConnection = ({ nodeId }: { nodeId: string }) => {
    document.removeEventListener('mousemove', handleMouseMove);
    
    if (tempConnection.value.isActive && tempConnection.value.sourceId !== nodeId) {
      const sourceNode = nodes.value.find(n => n.id === tempConnection.value.sourceId);
      const targetNode = nodes.value.find(n => n.id === nodeId);
      
      if (sourceNode && targetNode) {
        if (!sourceNode.children) {
          sourceNode.children = [];
        }
        // 检查是否已存在相同的连线
        if (!sourceNode.children.includes(nodeId)) {
          sourceNode.children.push(nodeId);
          sourceNode.isParent = true;
          
          // 计算连线的终点位置
          const points = calculateConnectionPoints(sourceNode, targetNode);
          tempConnection.value.endX = points.endX;
          tempConnection.value.endY = points.endY;
          
          // 更新连线的路径
          const newEdge = {
            sourceId: sourceNode.id,
            targetId: nodeId,
            path: getBezierPath(
              { x: points.startX, y: points.startY },
              { x: points.endX, y: points.endY }
            )
          };
          edges.value = [...edges.value, newEdge];
        }
      }
    }
    
    tempConnection.value.isActive = false;
  };

  // 新增函数：创建新节点
  const addNode = () => {
    const newNode: Node = {
      id: `n${Date.now()}`,
      x: 200,
      y: 150,
      type: NodeType.NORMAL,
      isParent: false
    };
    nodes.value.push(newNode);
  };

  // 删除节点
  const deleteNode = (nodeId: string) => {
    const index = nodes.value.findIndex(n => n.id === nodeId);
    if (index !== -1) {
      // 清理相关边
      nodes.value.forEach(node => {
        if (node.children) {
          node.children = node.children.filter(id => id !== nodeId);
          if (node.children.length === 0) {
            node.isParent = false;
          }
        }
      });
      nodes.value.splice(index, 1);
    }
  };
  

  

  
  // 拖拽逻辑
  const handleDragStart = (event: DragEvent, node: Node) => {
    if (event.dataTransfer) {
      event.dataTransfer.setData('text', node.id);
      
      // 计算鼠标相对于节点的偏移量
      const nodeElement = event.target as HTMLElement;
      const nodeRect = nodeElement.getBoundingClientRect();
      const offset = {
        x: event.clientX - nodeRect.left,
        y: event.clientY - nodeRect.top
      };
      
      // 将偏移量信息存储在dataTransfer中
      event.dataTransfer.setData('offset', JSON.stringify(offset));
    }
  };
  
  const handleDrop = (event: DragEvent) => {
    const nodeId = event.dataTransfer?.getData('text');
    const droppedNode = nodes.value.find(n => n.id === nodeId);
    
    if (droppedNode) {
      const container = document.querySelector('.workflow-container') as HTMLDivElement;
      const containerRect = container.getBoundingClientRect();
      const offset = JSON.parse(event.dataTransfer?.getData('offset') || '{ "x": 0, "y": 0 }');
      
      // 计算节点新位置，考虑鼠标偏移量、容器滚动位置和边界
      const x = event.clientX - containerRect.left - offset.x + container.scrollLeft;
      const y = event.clientY - containerRect.top - offset.y + container.scrollTop;
      
      droppedNode.x = Math.max(0, x);
      droppedNode.y = Math.max(0, y);
    }
  };
  
  // 辅助方法：获取与节点相关的边
  const getEdgesForNode = (node: Node) => {
    return edges.value.filter(edge => 
      edge.sourceId === node.id || edge.targetId === node.id
    );
  };
  </script>
  
  <style scoped>
  .workflow-page {
    width: 100%;
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .workflow-container {
    flex: 1;
    position: relative;
    width: 100%;
    min-width: 800px;
    min-height: 600px;
    border: 2px dashed #aaa;
    background-color: #ffffff;
    background-image: radial-gradient(#e1e1e1 1px, transparent 1px);
    background-size: 20px 20px;
    overflow: auto;
  }

  .toolbar {
    padding: 10px 20px;
    background-color: #fff;
    border-bottom: 1px solid #eee;
    display: flex;
    justify-content: flex-end;
    width: 100%;
    box-sizing: border-box;
  }

  .toolbar-right {
    margin-left: auto;
  }

  .add-node-btn {
    padding: 8px 16px;
    background-color: #2196f3;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s;
  }

  .add-node-btn:hover {
    background-color: #1976d2;
  }

  .connections {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }

  .edge-path {
    transition: all 0.3s ease;
    pointer-events: all;
    cursor: pointer;
  }

  .edge-path:hover {
    stroke: #1976d2;
    stroke-width: 3;
  }
  </style>
  